package com.unknowpupil.sell.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.unknowpupil.sell.common.BasePage;
import com.unknowpupil.sell.common.enums.ErrorCodeEnum;
import com.unknowpupil.sell.common.enums.PublicEnums;
import com.unknowpupil.sell.converter.OrderMaster2OrderDTO;
import com.unknowpupil.sell.domain.OrderDetail;
import com.unknowpupil.sell.domain.OrderMaster;
import com.unknowpupil.sell.domain.ProductInfo;
import com.unknowpupil.sell.dto.CartDTO;
import com.unknowpupil.sell.dto.OrderDTO;
import com.unknowpupil.sell.exception.SellException;
import com.unknowpupil.sell.mapper.OrderDetailMapper;
import com.unknowpupil.sell.mapper.OrderMasterMapper;
import com.unknowpupil.sell.service.IOrderMasterService;
import com.unknowpupil.sell.service.IProductInfoService;
import com.unknowpupil.sell.service.PayServer;
import com.unknowpupil.sell.utils.KeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author AutoGenerator
 */
@Service
@Slf4j
public class OrderMasterServiceImpl extends ServiceImpl<OrderMasterMapper, OrderMaster> implements IOrderMasterService {
    @Autowired
    private IProductInfoService productInfoService;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private PayServer payServer;

    @Override
    @Transactional
    public OrderDTO create(OrderDTO orderDTO) {
//        List<CartDTO> cartDTOList = Lists.newArrayList(); //1
        String orderId = KeyUtil.genUniqueKey();
        //定义总价
        BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);

        //1.查询商品（数量，价格）
        for (OrderDetail orderDetail : orderDTO.getOrderDetailList()) {
            ProductInfo productInfo = productInfoService.getById(orderDetail.getProductId());
            if (productInfo == null) {
                throw new SellException(ErrorCodeEnum.PRODUCT_NOT_EXIST);
            }
            //2.计算总价
            orderAmount = productInfo.getProductPrice()
                    .multiply(new BigDecimal(orderDetail.getProductQuantity()))
                    .add(orderAmount);

            BeanUtils.copyProperties(productInfo,orderDetail);
            orderDetail.setDetailId(KeyUtil.genUniqueKey());
            orderDetail.setOrderId(orderId);
            orderDTO.setOrderId(orderId);

            orderDetailMapper.insert(orderDetail);
//            CartDTO cartDTO = new CartDTO(orderDetail.getProductId(),orderDetail.getProductQuantity());
//            cartDTOList.add(cartDTO); //1  不用污染代码

        }
        //3写入订单
        OrderMaster orderMaster = new OrderMaster();

        BeanUtils.copyProperties(orderDTO,orderMaster);
        orderMaster.setOrderId(orderId);
        orderMaster.setOrderStatus(PublicEnums.OrderStatusEnums.NEW.getCode());
        orderMaster.setPayStatus(PublicEnums.PayStatusEnums.WAIT.getCode());
        orderMaster.setOrderAmount(orderAmount);

        baseMapper.insert(orderMaster);
        //扣库存
        List<CartDTO> cartDTOList =  orderDTO.getOrderDetailList().stream().map(e->
            new CartDTO(e.getProductId(),e.getProductQuantity())
        ).collect(Collectors.toList());
        productInfoService.decreaseStock(cartDTOList);
        return orderDTO;
    }

    @Override
    public OrderDTO finOne(String orderId) {
        OrderMaster orderMaster = baseMapper.selectById(orderId);
        if(orderMaster==null){
            throw new  SellException(ErrorCodeEnum.ORDER_NOT_EXIST);
        }
        List<OrderDetail> orderDetailList = orderDetailMapper.selectList(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId,orderId));
        if(orderDetailList==null){
            throw new SellException(ErrorCodeEnum.ORDER_NOT_EXIST);
        }
        OrderDTO orderDTO = new OrderDTO();
        BeanUtils.copyProperties(orderMaster,orderDTO);
        orderDTO.setOrderDetailList(orderDetailList);
        return orderDTO;
    }

    @Override
    public IPage<OrderDTO> findListWithPage(String buyerOpenId, BasePage page) {
        IPage<OrderMaster> result = baseMapper.selectPage(new Page<OrderMaster>(page.getCurrent(),page.getSize()),new LambdaQueryWrapper<OrderMaster>().eq(OrderMaster::getBuyerOpenid,buyerOpenId));
        IPage<OrderDTO> orderDTOIPage = new Page<>();
        List<OrderDTO> convert = OrderMaster2OrderDTO.convert(result.getRecords());
        BeanUtils.copyProperties(orderDTOIPage,page);
        orderDTOIPage.setRecords(convert);
        return orderDTOIPage;
    }

    @Override
    public OrderDTO cancel(OrderDTO orderDTO) {
        OrderMaster orderMaster = new OrderMaster();

        //判断订单状态
        if(!orderDTO.getOrderStatus().equals(PublicEnums.OrderStatusEnums.NEW.getCode())){
            log.error("[取消订单] 订单状态不正确，orderId={}，orderStatus={}",orderDTO.getOrderId(),orderDTO.getOrderStatus());
            throw new SellException(ErrorCodeEnum.ORDER_STATUS_ERROR);
        }
        // 修改订单状态
        orderDTO.setOrderStatus(PublicEnums.OrderStatusEnums.CANCEL.getCode());
        BeanUtils.copyProperties(orderDTO,orderMaster);
        int i = baseMapper.updateById(orderMaster);
        if(i<0){
            log.error("[取消订单] 更新失败，orderMaster={}",orderMaster);
            throw new SellException(ErrorCodeEnum.BUSINESS_FAIL);
        }
        //返回库存
         if(orderDTO.getOrderDetailList()==null){
             log.error("[取消订单] 订单详情为空，orderDto={}",orderDTO);
             throw new SellException(ErrorCodeEnum.ORDER_DETAIL_EMPTY);
         }
         List<CartDTO> cartDTOList = orderDTO.getOrderDetailList().stream().map(e->new CartDTO(e.getProductId(),e.getProductQuantity())).collect(Collectors.toList());

         productInfoService.increaseStock(cartDTOList);

        //如果已经支付，需要退款
            if(orderDTO.getPayStatus().equals(PublicEnums.PayStatusEnums.SUCCESS.getCode())){
                //TODO
                payServer.refound(orderDTO);
            }

        return orderDTO;
    }

    @Override
    @Transactional
    public OrderDTO finish(OrderDTO orderDTO) {
        //判断订单状态
        if(!orderDTO.getOrderStatus().equals(PublicEnums.OrderStatusEnums.NEW.getCode())){
            log.error("【完结订单】 订单状态不正确，orderId={},orderStatus={}",orderDTO.getOrderId(),orderDTO.getOrderStatus());
            throw new SellException(ErrorCodeEnum.ORDER_STATUS_ERROR);

        }

        //修改状态
        orderDTO.setOrderStatus(PublicEnums.OrderStatusEnums.FINISHED.getCode());
        OrderMaster orderMaster = new OrderMaster();
        BeanUtils.copyProperties(orderDTO,orderMaster);
        try {
            int i = baseMapper.updateById(orderMaster);
        }catch (Exception e){
            log.error("[完结订单] 更新失败，orderMaster={}",orderMaster);
            throw new SellException(1,e.getMessage());
        }
        return orderDTO;
    }

    @Override
    @Transactional
    public OrderDTO paid(OrderDTO orderDTO) {
        //判断支付状态，
        if(!orderDTO.getOrderStatus().equals(PublicEnums.OrderStatusEnums.NEW.getCode())){
            log.error("【订单支付完成】 订单状态不正确，orderId={},orderStatus={}",orderDTO.getOrderId(),orderDTO.getOrderStatus());
            throw new SellException(ErrorCodeEnum.ORDER_STATUS_ERROR);
        }
        //修改支付状态
        if(!orderDTO.getPayStatus().equals(PublicEnums.PayStatusEnums.WAIT.getCode())){
            log.error("【订单支付完成】 订单支付状态不正确，orderId={},orderStatus={}",orderDTO.getOrderId(),orderDTO.getPayStatus());
            throw new SellException(ErrorCodeEnum.PAY_STATUS_ERROR);

        }
        orderDTO.setPayStatus(PublicEnums.PayStatusEnums.SUCCESS.getCode());
        OrderMaster orderMaster = new OrderMaster();
        BeanUtils.copyProperties(orderDTO,orderMaster);
        try {
            int i = baseMapper.updateById(orderMaster);
        }catch (Exception e){
            log.error("[订单支付完成] 更新失败，orderMaster={}",orderMaster);
            throw new SellException(1,e.getMessage());
        }
        return orderDTO;
    }
}
